
#ifndef __IOCTLS_H__
#define __IOCTLS_H__

#include "kernel-shared.h"
#include "general-types.h"

// 0x22403f

#define IOCTL_IRPMNDRV_CONNECT                         CTL_CODE(FILE_DEVICE_UNKNOWN, 0x01, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_DISCONNECT                      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x02, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_GET_RECORD                      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x03, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_HOOK_DRIVER                     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x04, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_UNHOOK_DRIVER                   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x05, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_HOOK_ADD_DEVICE                 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x06, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_HOOK_REMOVE_DEVICE              CTL_CODE(FILE_DEVICE_UNKNOWN, 0x07, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_GET_DRIVER_DEVICE_INFO          CTL_CODE(FILE_DEVICE_UNKNOWN, 0x08, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_IRPMNDRV_HOOK_DRIVER_SET_INFO            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x09, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_HOOK_DRIVER_MONITORING_CHANGE   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0a, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMONDRV_HOOK_GET_INFO                  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0b, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_IRPMONDRV_HOOK_OPEN                      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0c, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_IRPMONDRV_HOOK_CLOSE                     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0d, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_IRPMNDRV_HOOK_DRIVER_GET_INFO            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0e, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_HOOK_DEVICE_SET_INFO            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0f, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_IRPMNDRV_HOOK_DEVICE_GET_INFO            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x10, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_CLASS_WATCH_REGISTER			   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x11, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_CLASS_WATCH_UNREGISTER		   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x12, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_CLASS_WATCH_ENUM				   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x13, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_IRPMNDRV_DRIVER_WATCH_REGISTER		   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x14, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_DRIVER_WATCH_UNREGISTER		   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x15, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_DRIVER_WATCH_ENUM			   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x16, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_IRPMNDRV_EMULATE_DRVDEV				   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x17, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_IRPMNDRV_EMULATE_PROCESS				   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x18, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_IRPMNDRV_QUEUE_CLEAR					   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x19, METHOD_NEITHER, FILE_WRITE_ACCESS)
#define IOCTL_IRPMNDRV_SETTINGS_QUERY                  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1a, METHOD_NEITHER, FILE_READ_ACCESS)
#define IOCTL_IRPMNDRV_SETTINGS_SET					   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1b, METHOD_NEITHER, FILE_WRITE_ACCESS)


typedef struct _IOCTL_IRPMNDRV_CONNECT_INPUT {
	HANDLE SemaphoreHandle;
} IOCTL_IRPMNDRV_CONNECT_INPUT, *PIOCTL_IRPMNDRV_CONNECT_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DRIVER_INPUT {
	DRIVER_MONITOR_SETTINGS MonitorSettings;
	ULONG DriverNameLength;
	BOOLEAN DeviceExtensionHook;
	// Driver name length
} IOCTL_IRPMNDRV_HOOK_DRIVER_INPUT, *PIOCTL_IRPMNDRV_HOOK_DRIVER_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DRIVER_OUTPUT {
	HANDLE HookHandle;
	PVOID ObjectId;
} IOCTL_IRPMNDRV_HOOK_DRIVER_OUTPUT, *PIOCTL_IRPMNDRV_HOOK_DRIVER_OUTPUT;

typedef struct _IOCTL_IRPMNDRV_UNHOOK_DRIVER_INPUT {
	HANDLE HookHandle;
} IOCTL_IRPMNDRV_UNHOOK_DRIVER_INPUT, *PIOCTL_IRPMNDRV_UNHOOK_DRIVER_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_ADD_DEVICE_INPUT {
	UCHAR IRPSettings[0x1c];
	UCHAR FastIoSettings[FastIoMax];
	PVOID DeviceAddress;
	ULONG DeviceNameLength;
	BOOLEAN HookByName;
	BOOLEAN IRPSettingsSpecified;
	BOOLEAN FastIoSettingsSpecified;
	// Device name
} IOCTL_IRPMNDRV_HOOK_ADD_DEVICE_INPUT, *PIOCTL_IRPMNDRV_HOOK_ADD_DEVICE_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_ADD_DEVICE_OUTPUT {
	HANDLE DeviceHandle;
	PVOID ObjectId;
} IOCTL_IRPMNDRV_HOOK_ADD_DEVICE_OUTPUT, *PIOCTL_IRPMNDRV_HOOK_ADD_DEVICE_OUTPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_REMOVE_DEVICE_INPUT {
	HANDLE DeviceHandle;
} IOCTL_IRPMNDRV_HOOK_REMOVE_DEVICE_INPUT, *PIOCTL_IRPMNDRV_HOOK_REMOVE_DEVICE_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DRIVER_SET_INFO_INPUT {
	HANDLE DriverHandle;
	DRIVER_MONITOR_SETTINGS Settings;
} IOCTL_IRPMNDRV_HOOK_DRIVER_SET_INFO_INPUT, *PIOCTL_IRPMNDRV_HOOK_DRIVER_SET_INFO_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DRIVER_GET_INFO_INPUT {
	HANDLE DriverHandle;
} IOCTL_IRPMNDRV_HOOK_DRIVER_GET_INFO_INPUT, *PIOCTL_IRPMNDRV_HOOK_DRIVER_GET_INFO_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DRIVER_GET_INFO_OUTPUT {
	DRIVER_MONITOR_SETTINGS Settings;
	BOOLEAN MonitoringEnabled;
} IOCTL_IRPMNDRV_HOOK_DRIVER_GET_INFO_OUTPUT, *PIOCTL_IRPMNDRV_HOOK_DRIVER_GET_INFO_OUTPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DRIVER_MONITORING_CHANGE_INPUT {
	HANDLE DriverHandle;
	BOOLEAN EnableMonitoring;
} IOCTL_IRPMNDRV_HOOK_DRIVER_MONITORING_CHANGE_INPUT, *PIOCTL_IRPMNDRV_HOOK_DRIVER_MONITORING_CHANGE_INPUT;

typedef struct _IOCTL_IRPMONDRV_HOOK_GET_INFO_OUTPUT {
	HOOKED_OBJECTS_INFO Info;
} IOCTL_IRPMONDRV_HOOK_GET_INFO_OUTPUT, *PIOCTL_IRPMONDRV_HOOK_GET_INFO_OUTPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DEVICE_SET_INFO_INPUT {
	UCHAR IRPSettings[0x1c];
	UCHAR FastIoSettings[FastIoMax];
	HANDLE DeviceHandle;
	BOOLEAN MonitoringEnabled;
	BOOLEAN IRPSettingsSpecified;
	BOOLEAN FastIoSettingsSpecified;
} IOCTL_IRPMNDRV_HOOK_DEVICE_SET_INFO_INPUT, *PIOCTL_IRPMNDRV_HOOK_DEVICE_SET_INFO_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DEVICE_GET_INFO_INPUT {
	HANDLE DeviceHandle;
} IOCTL_IRPMNDRV_HOOK_DEVICE_GET_INFO_INPUT, *PIOCTL_IRPMNDRV_HOOK_DEVICE_GET_INFO_INPUT;

typedef struct _IOCTL_IRPMNDRV_HOOK_DEVICE_GET_INFO_OUTPUT {
	UCHAR IRPSettings[0x1C];
	UCHAR FastIoSettings[FastIoMax];
	BOOLEAN MonitoringEnabled;
} IOCTL_IRPMNDRV_HOOK_DEVICE_GET_INFO_OUTPUT, *PIOCTL_IRPMNDRV_HOOK_DEVICE_GET_INFO_OUTPUT;

typedef enum _EHandleType {
	ehtUnknown,
	ehtDriver,
	ehtDevice
} EHandletype, *PEHandleType;

typedef struct _IOCTL_IRPMONDRV_HOOK_OPEN_INPUT {
	EHandletype ObjectType;
	PVOID ObjectId;
} IOCTL_IRPMONDRV_HOOK_OPEN_INPUT, *PIOCTL_IRPMONDRV_HOOK_OPEN_INPUT;

typedef struct _IOCTL_IRPMONDRV_HOOK_OPEN_OUTPUT {
	HANDLE Handle;
} IOCTL_IRPMONDRV_HOOK_OPEN_OUTPUT, *PIOCTL_IRPMONDRV_HOOK_OPEN_OUTPUT;

typedef struct _IOCTL_IRPMONDRV_HOOK_CLOSE_INPUT {
	EHandletype ObjectType;
	HANDLE Handle;
} IOCTL_IRPMONDRV_HOOK_CLOSE_INPUT, *PIOCTL_IRPMONDRV_HOOK_CLOSE_INPUT;

/************************************************************************/
/*                   CLASS WATCH                                        */
/************************************************************************/


typedef struct _IOCTL_IRPMNDRV_CLASS_WATCH_REGISTER_INPUT {
	ULONG Flags;
	union {
		GUID ClassGuidBinary;
		WCHAR ClassGuidString[38];
	} Data;
} IOCTL_IRPMNDRV_CLASS_WATCH_REGISTER_INPUT, *PIOCTL_IRPMNDRV_CLASS_WATCH_REGISTER_INPUT;

typedef struct _IOCTL_IRPMNDRV_CLASS_WATCH_UNREGISTER_INPUT {
	ULONG Flags;
	union {
		GUID ClassGuidBinary;
		WCHAR ClassGuidString[38];
	} Data;
} IOCTL_IRPMNDRV_CLASS_WATCH_UNREGISTER_INPUT, *PIOCTL_IRPMNDRV_CLASS_WATCH_UNREGISTER_INPUT;

typedef struct _IOCTL_IRPMNDRV_CLASS_WATCH_ENUM_OUTPUT {
	ULONG Count;
	CLASS_WATCH_ENTRY Entries[1];
} IOCTL_IRPMNDRV_CLASS_WATCH_ENUM_OUTPUT, *PIOCTL_IRPMNDRV_CLASS_WATCH_OUTPUT;

/************************************************************************/
/*                       DRIVER NAME WATCH                              */
/************************************************************************/

typedef struct _IOCTL_IRPMNDRV_DRIVER_WATCH_REGISTER_INPUT {
	DRIVER_MONITOR_SETTINGS MonitorSettings;
	USHORT NameLength;
}  IOCTL_IRPMNDRV_DRIVER_WATCH_REGISTER_INPUT, *PIOCTL_IRPMNDRV_DRIVER_WATCH_REGISTER_INPUT;

typedef struct _IOCTL_IRPMNDRV_DRIVER_WATCH_UNREGISTER_INPUT {
	USHORT NameLength;
}  IOCTL_IRPMNDRV_DRIVER_WATCH_UNREGISTER_INPUT, *PIOCTL_IRPMNDRV_DRIVER_WATCH_UNREGISTER_INPUT;

typedef struct _IOCTL_IRPMNDRV_DRIVER_WATCH_ENUM_OUTPUT {
	ULONG Count;
	DRIVER_NAME_WATCH_ENTRY Entry;
}  IOCTL_IRPMNDRV_DRIVER_WATCH_ENUM_OUTPUT, *PIOCTL_IRPMNDRV_DRIVER_WATCH_ENUM_OUTPUT;

typedef struct _IOCTL_IRPMNDRV_SETTINGS_QUERY_OUTPUT {
	IRPMNDRV_SETTINGS Settings;
} IOCTL_IRPMNDRV_SETTINGS_QUERY_OUTPUT, *PIOCTL_IRPMNDRV_SETTINGS_QUERY_OUTPUT;

typedef struct _IOCTL_IRPMNDRV_SETTINGS_SET_INPUT {
	IRPMNDRV_SETTINGS Settings;
	BOOLEAN Save;
} IOCTL_IRPMNDRV_SETTINGS_SET_INPUT, *PIOCTL_IRPMNDRV_SETTINGS_SET_INPUT;


#endif
